home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / var / lib / python-support / python2.6 / rdflib / store / MySQL.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2009-04-20  |  16.7 KB  |  488 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. from __future__ import generators
  5. from rdflib import BNode
  6. from rdflib.store import Store, VALID_STORE, CORRUPTED_STORE, NO_STORE, UNKNOWN
  7. from rdflib.Literal import Literal
  8. from pprint import pprint
  9. import MySQLdb
  10. import sys
  11. from rdflib.term_utils import *
  12. from rdflib.Graph import QuotedGraph
  13. from rdflib.store.REGEXMatching import REGEXTerm, NATIVE_REGEX, PYTHON_REGEX
  14. from rdflib.store.AbstractSQLStore import *
  15. from FOPLRelationalModel.RelationalHash import IdentifierHash, LiteralHash, RelationalHash, GarbageCollectionQUERY
  16. from FOPLRelationalModel.BinaryRelationPartition import *
  17. from FOPLRelationalModel.QuadSlot import *
  18. Any = None
  19.  
  20. def ParseConfigurationString(config_string):
  21.     '''
  22.     Parses a configuration string in the form:
  23.     key1=val1,key2=val2,key3=val3,...
  24.     The following configuration keys are expected (not all are required):
  25.     user
  26.     password
  27.     db
  28.     host
  29.     port (optional - defaults to 3306)
  30.     '''
  31.     kvDict = []([ (part.split('=')[0], part.split('=')[-1]) for part in config_string.split(',') ])
  32.     for requiredKey in [
  33.         'user',
  34.         'db',
  35.         'host']:
  36.         if not requiredKey in kvDict:
  37.             raise AssertionError
  38.     
  39.     if 'password' not in kvDict:
  40.         kvDict['password'] = ''
  41.     
  42.     return kvDict
  43.  
  44.  
  45. def createTerm(termString, termType, store, objLanguage = None, objDatatype = None):
  46.     if termType == 'L':
  47.         cache = store.literalCache.get((termString, objLanguage, objDatatype))
  48.         if cache is not None:
  49.             return cache
  50.         rt = Literal(termString, objLanguage, objDatatype)
  51.         store.literalCache[(termString, objLanguage, objDatatype)] = rt
  52.         return rt
  53.     termType == 'L'
  54.     if termType == 'F':
  55.         cache = store.otherCache.get((termType, termString))
  56.         if cache is not None:
  57.             return cache
  58.         rt = QuotedGraph(store, URIRef(termString))
  59.         store.otherCache[(termType, termString)] = rt
  60.         return rt
  61.     termType == 'F'
  62.     if termType == 'B':
  63.         cache = store.bnodeCache.get(termString)
  64.         if cache is not None:
  65.             return cache
  66.         rt = TERM_INSTANCIATION_DICT[termType](termString)
  67.         store.bnodeCache[termString] = rt
  68.         return rt
  69.     termType == 'B'
  70.     if termType == 'U':
  71.         cache = store.uriCache.get(termString)
  72.         if cache is not None:
  73.             return cache
  74.         rt = URIRef(termString)
  75.         store.uriCache[termString] = rt
  76.         return rt
  77.     termType == 'U'
  78.     cache = store.otherCache.get((termType, termString))
  79.     if cache is not None:
  80.         return cache
  81.     rt = TERM_INSTANCIATION_DICT[termType](termString)
  82.     store.otherCache[(termType, termString)] = rt
  83.     return rt
  84.  
  85.  
  86. def extractTriple(tupleRt, store, hardCodedContext = None):
  87.     (subject, sTerm, predicate, pTerm, obj, oTerm, rtContext, cTerm, objDatatype, objLanguage) = tupleRt
  88.     if not rtContext is not None or rtContext:
  89.         pass
  90.     context = hardCodedContext.identifier
  91.     s = createTerm(subject, sTerm, store)
  92.     p = createTerm(predicate, pTerm, store)
  93.     o = createTerm(obj, oTerm, store, objLanguage, objDatatype)
  94.     (graphKlass, idKlass) = constructGraph(cTerm)
  95.     return (s, p, o, (graphKlass, idKlass, context))
  96.  
  97.  
  98. class MySQL(Store):
  99.     '''
  100.     MySQL implementation of FOPL Relational Model as an rdflib Store
  101.     '''
  102.     context_aware = True
  103.     formula_aware = True
  104.     transaction_aware = True
  105.     regex_matching = NATIVE_REGEX
  106.     
  107.     def __init__(self, identifier = None, configuration = None):
  108.         if not identifier or identifier:
  109.             pass
  110.         self.identifier = 'hardcoded'
  111.         self._internedId = INTERNED_PREFIX + sha.new(self.identifier).hexdigest()[:10]
  112.         self.idHash = IdentifierHash(self._internedId)
  113.         self.valueHash = LiteralHash(self._internedId)
  114.         self.binaryRelations = NamedBinaryRelations(self._internedId, self.idHash, self.valueHash)
  115.         self.literalProperties = NamedLiteralProperties(self._internedId, self.idHash, self.valueHash)
  116.         self.aboxAssertions = AssociativeBox(self._internedId, self.idHash, self.valueHash)
  117.         self.tables = [
  118.             self.binaryRelations,
  119.             self.literalProperties,
  120.             self.aboxAssertions,
  121.             self.idHash,
  122.             self.valueHash]
  123.         self.createTables = [
  124.             self.idHash,
  125.             self.valueHash,
  126.             self.binaryRelations,
  127.             self.literalProperties,
  128.             self.aboxAssertions]
  129.         self.hashes = [
  130.             self.idHash,
  131.             self.valueHash]
  132.         self.partitions = [
  133.             self.literalProperties,
  134.             self.binaryRelations,
  135.             self.aboxAssertions]
  136.         self.STRONGLY_TYPED_TERMS = False
  137.         self._db = None
  138.         if configuration is not None:
  139.             self.open(configuration)
  140.         
  141.         self.cacheHits = 0
  142.         self.cacheMisses = 0
  143.         self.literalCache = { }
  144.         self.uriCache = { }
  145.         self.bnodeCache = { }
  146.         self.otherCache = { }
  147.  
  148.     
  149.     def executeSQL(self, cursor, qStr, params = None, paramList = False):
  150.         '''
  151.         Overridded in order to pass params seperate from query for MySQLdb
  152.         to optimize
  153.         '''
  154.         if params is None:
  155.             cursor.execute(qStr)
  156.         elif paramList:
  157.             []([], [ tuple(item) for item in params ])
  158.         else:
  159.             cursor.execute(qStr, tuple(params))
  160.  
  161.     
  162.     def open(self, configuration, create = False):
  163.         '''
  164.         Opens the store specified by the configuration string. If
  165.         create is True a store will be created if it does not already
  166.         exist. If create is False and a store does not already exist
  167.         an exception is raised. An exception is also raised if a store
  168.         exists, but there is insufficient permissions to open the
  169.         store.
  170.         '''
  171.         configDict = ParseConfigurationString(configuration)
  172.         if create:
  173.             test_db = MySQLdb.connect(user = configDict['user'], passwd = configDict['password'], db = 'test', port = configDict['port'], host = configDict['host'])
  174.             c = test_db.cursor()
  175.             c.execute('SET AUTOCOMMIT=0')
  176.             c.execute('SHOW DATABASES')
  177.             if (configDict['db'].encode('utf-8'),) not in c.fetchall():
  178.                 print "creating %s (doesn't exist)" % configDict['db']
  179.                 c.execute('CREATE DATABASE %s' % (configDict['db'],))
  180.                 test_db.commit()
  181.                 c.close()
  182.                 test_db.close()
  183.             
  184.             db = MySQLdb.connect(user = configDict['user'], passwd = configDict['password'], db = configDict['db'], port = configDict['port'], host = configDict['host'])
  185.             c = db.cursor()
  186.             c.execute('SET AUTOCOMMIT=0')
  187.             c.execute(CREATE_NS_BINDS_TABLE % self._internedId)
  188.             for kb in self.createTables:
  189.                 c.execute(kb.createSQL())
  190.                 if isinstance(kb, RelationalHash) and kb.defaultSQL():
  191.                     c.execute(kb.defaultSQL())
  192.                     continue
  193.             
  194.             db.commit()
  195.             c.close()
  196.             db.close()
  197.         
  198.         
  199.         try:
  200.             port = int(configDict['port'])
  201.         except:
  202.             raise ArithmeticError('MySQL port must be a valid integer')
  203.  
  204.         self._db = MySQLdb.connect(user = configDict['user'], passwd = configDict['password'], db = configDict['db'], port = port, host = configDict['host'])
  205.         self._db.autocommit(False)
  206.         c = self._db.cursor()
  207.         c.execute('SHOW DATABASES')
  208.         rt = c.fetchall()
  209.         if (configDict['db'].encode('utf-8'),) in rt:
  210.             for tn in self.tables:
  211.                 c.execute("show tables like '%s'" % (tn,))
  212.                 rt = c.fetchall()
  213.                 if not rt:
  214.                     sys.stderr.write("table %s Doesn't exist\n" % tn)
  215.                     return CORRUPTED_STORE
  216.             
  217.             return VALID_STORE
  218.         return NO_STORE
  219.  
  220.     
  221.     def destroy(self, configuration):
  222.         '''
  223.         FIXME: Add documentation
  224.         '''
  225.         configDict = ParseConfigurationString(configuration)
  226.         msql_db = MySQLdb.connect(user = configDict['user'], passwd = configDict['password'], db = configDict['db'], port = configDict['port'], host = configDict['host'])
  227.         msql_db.autocommit(False)
  228.         c = msql_db.cursor()
  229.         for tbl in self.tables + [
  230.             '%s_namespace_binds' % self._internedId]:
  231.             
  232.             try:
  233.                 c.execute('DROP table %s' % tbl)
  234.             continue
  235.             except Exception:
  236.                 e = None
  237.                 print 'unable to drop table: %s' % tbl
  238.                 print e
  239.                 continue
  240.             
  241.  
  242.         
  243.         print 'Destroyed Close World Universe %s ( in MySQL database %s)' % (self.identifier, configDict['db'])
  244.         msql_db.commit()
  245.         msql_db.close()
  246.  
  247.     
  248.     def commit(self):
  249.         ''' '''
  250.         self._db.commit()
  251.  
  252.     
  253.     def rollback(self):
  254.         ''' '''
  255.         self._db.rollback()
  256.  
  257.     
  258.     def gc(self):
  259.         '''
  260.         Purges unreferenced identifiers / values - expensive
  261.         '''
  262.         c = self._db.cursor()
  263.         purgeQueries = GarbageCollectionQUERY(self.idHash, self.valueHash, self.binaryRelations, self.aboxAssertions, self.literalProperties)
  264.         for q in purgeQueries:
  265.             self.executeSQL(c, q)
  266.         
  267.  
  268.     
  269.     def add(self, .1, context = None, quoted = False):
  270.         ''' Add a triple to the store of triples. '''
  271.         (subject, predicate, obj) = .1
  272.         qSlots = genQuadSlots([
  273.             subject,
  274.             predicate,
  275.             obj,
  276.             context])
  277.         if predicate == RDF.type:
  278.             kb = self.aboxAssertions
  279.         elif isinstance(obj, Literal):
  280.             kb = self.literalProperties
  281.         else:
  282.             kb = self.binaryRelations
  283.         kb.insertRelations([
  284.             qSlots])
  285.         kb.flushInsertions(self._db)
  286.  
  287.     
  288.     def addN(self, quads):
  289.         '''
  290.         Adds each item in the list of statements to a specific context. The quoted argument
  291.         is interpreted by formula-aware stores to indicate this statement is quoted/hypothetical.
  292.         Note that the default implementation is a redirect to add
  293.         '''
  294.         for s, p, o, c in quads:
  295.             if not c is not None:
  296.                 raise AssertionError, 'Context associated with %s %s %s is None!' % (s, p, o)
  297.             qSlots = genQuadSlots([
  298.                 s,
  299.                 p,
  300.                 o,
  301.                 c])
  302.             if p == RDF.type:
  303.                 kb = self.aboxAssertions
  304.             elif isinstance(o, Literal):
  305.                 kb = self.literalProperties
  306.             else:
  307.                 kb = self.binaryRelations
  308.             kb.insertRelations([
  309.                 qSlots])
  310.         
  311.         for kb in self.partitions:
  312.             if kb.pendingInsertions:
  313.                 kb.flushInsertions(self._db)
  314.                 continue
  315.         
  316.  
  317.     
  318.     def remove(self, .1, context):
  319.         ''' Remove a triple from the store '''
  320.         (subject, predicate, obj) = .1
  321.         targetBRPs = BinaryRelationPartitionCoverage((subject, predicate, obj, context), self.partitions)
  322.         c = self._db.cursor()
  323.         for brp in targetBRPs:
  324.             query = 'DELETE %s from %s %s WHERE ' % (brp, brp, brp.generateHashIntersections())
  325.             (whereClause, whereParameters) = brp.generateWhereClause((subject, predicate, obj, context))
  326.             self.executeSQL(c, query + whereClause, params = whereParameters)
  327.         
  328.         c.close()
  329.  
  330.     
  331.     def triples(self, .1, context = None):
  332.         (subject, predicate, obj) = .1
  333.         c = self._db.cursor()
  334.         if context is None or isinstance(context.identifier, REGEXTerm):
  335.             rt = PatternResolution((subject, predicate, obj, context), c, self.partitions, fetchall = False)
  336.         else:
  337.             rt = PatternResolution((subject, predicate, obj, context), c, self.partitions, orderByTriple = False, fetchall = False)
  338.         while rt:
  339.             (graphKlass, idKlass, graphId) = (s, p, o)
  340.             if not context is None or isinstance(context.identifier, REGEXTerm) or graphKlass(self, idKlass(graphId)):
  341.                 pass
  342.             currentContext = context
  343.             contexts = [
  344.                 currentContext]
  345.             yield ((s, p, o), (lambda .0: for c in .0:
  346. c)(contexts))
  347.             extractTriple(rt, self, context) if context is None or isinstance(context.identifier, REGEXTerm) else rt = next = c.fetchone()
  348.  
  349.     
  350.     def triples_choices(self, .1, context = None):
  351.         """
  352.         A variant of triples that can take a list of terms instead of a single
  353.         term in any slot.  Stores can implement this to optimize the response time
  354.         from the import default 'fallback' implementation, which will iterate
  355.         over each term in the list and dispatch to tripless
  356.         """
  357.         (subject, predicate, object_) = .1
  358.         if isinstance(object_, list):
  359.             if not not isinstance(subject, list):
  360.                 raise AssertionError, 'object_ / subject are both lists'
  361.             if not not isinstance(predicate, list):
  362.                 raise AssertionError, 'object_ / predicate are both lists'
  363.             for s1, p1, o1 in self.triples((subject, predicate, object_), context):
  364.                 cg = None
  365.                 yield ((s1, p1, o1), cg)
  366.                 None if not object_ else not isinstance(subject, list)
  367.             
  368.         elif isinstance(subject, list):
  369.             if not not isinstance(predicate, list):
  370.                 raise AssertionError, 'subject / predicate are both lists'
  371.             if not subject:
  372.                 subject = None
  373.             
  374.             for s1, p1, o1 in self.triples((subject, predicate, object_), context):
  375.                 cg = None
  376.                 yield ((s1, p1, o1), cg)
  377.             
  378.         elif isinstance(predicate, list):
  379.             if not not isinstance(subject, list):
  380.                 raise AssertionError, 'predicate / subject are both lists'
  381.             if not predicate:
  382.                 predicate = None
  383.             
  384.             for s1, p1, o1 in self.triples((subject, predicate, object_), context):
  385.                 cg = None
  386.                 yield ((s1, p1, o1), cg)
  387.             
  388.         
  389.  
  390.     
  391.     def __repr__(self):
  392.         c = self._db.cursor()
  393.         rtDict = { }
  394.         countRows = 'select count(*) from %s'
  395.         countContexts = 'select DISTINCT %s from %s'
  396.         unionSelect = []([ countContexts % (part.columnNames[CONTEXT], str(part)) for part in self.partitions ])
  397.         self.executeSQL(c, unionSelect)
  398.         ctxCount = len(c.fetchall())
  399.         for part in self.partitions:
  400.             self.executeSQL(c, countRows % part)
  401.             rowCount = c.fetchone()[0]
  402.             rtDict[str(part)] = rowCount
  403.         
  404.         return '<Parititioned MySQL N3 Store: %s context(s), %s classification(s), %s property/value assertion(s), and %s other relation(s)>' % (ctxCount, rtDict[str(self.aboxAssertions)], rtDict[str(self.literalProperties)], rtDict[str(self.binaryRelations)])
  405.  
  406.     
  407.     def __len__(self, context = None):
  408.         rows = []
  409.         countRows = 'select count(*) from %s'
  410.         c = self._db.cursor()
  411.         for part in self.partitions:
  412.             if context is not None:
  413.                 (whereClause, whereParams) = part.generateWhereClause((None, None, None, context.identifier))
  414.                 self.executeSQL(c, countRows % part + ' where ' + whereClause, whereParams)
  415.             else:
  416.                 self.executeSQL(c, countRows % part)
  417.             rowCount = c.fetchone()[0]
  418.             rows.append(rowCount)
  419.         
  420.         return reduce((lambda x, y: x + y), rows)
  421.  
  422.     
  423.     def contexts(self, triple = None):
  424.         c = self._db.cursor()
  425.         if triple:
  426.             (subject, predicate, obj) = triple
  427.         else:
  428.             subject = None
  429.             predicate = None
  430.             obj = None
  431.         rt = PatternResolution((subject, predicate, obj, None), c, self.partitions, fetchall = False, fetchContexts = True)
  432.         while rt:
  433.             (contextId, cTerm) = rt
  434.             (graphKlass, idKlass) = constructGraph(cTerm)
  435.             yield graphKlass(self, idKlass(contextId))
  436.             rt = c.fetchone()
  437.  
  438.     
  439.     def bind(self, prefix, namespace):
  440.         ''' '''
  441.         c = self._db.cursor()
  442.         
  443.         try:
  444.             self.executeSQL(c, "INSERT INTO %s_namespace_binds VALUES ('%s', '%s')" % (self._internedId, prefix, namespace))
  445.         except:
  446.             pass
  447.  
  448.         c.close()
  449.  
  450.     
  451.     def prefix(self, namespace):
  452.         ''' '''
  453.         c = self._db.cursor()
  454.         self.executeSQL(c, "select prefix from %s_namespace_binds where uri = '%s'" % (self._internedId, namespace))
  455.         rt = [ rtTuple[0] for rtTuple in c.fetchall() ]
  456.         c.close()
  457.         if not rt or rt[0]:
  458.             pass
  459.  
  460.     
  461.     def namespace(self, prefix):
  462.         ''' '''
  463.         c = self._db.cursor()
  464.         
  465.         try:
  466.             self.executeSQL(c, "select uri from %s_namespace_binds where prefix = '%s'" % (self._internedId, prefix))
  467.         except:
  468.             return None
  469.  
  470.         rt = [ rtTuple[0] for rtTuple in c.fetchall() ]
  471.         c.close()
  472.         if not rt or rt[0]:
  473.             pass
  474.  
  475.     
  476.     def namespaces(self):
  477.         ''' '''
  478.         c = self._db.cursor()
  479.         self.executeSQL(c, 'select prefix, uri from %s_namespace_binds where 1;' % self._internedId)
  480.         rt = c.fetchall()
  481.         c.close()
  482.         for prefix, uri in rt:
  483.             yield (prefix, uri)
  484.         
  485.  
  486.  
  487. CREATE_NS_BINDS_TABLE = '\nCREATE TABLE %s_namespace_binds (\n    prefix        varchar(20) UNIQUE not NULL,\n    uri           text,\n    PRIMARY KEY (prefix),\n    INDEX uri_index (uri(100))) ENGINE=InnoDB'
  488.